/*
 * Copyright 2007. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the GNU Lesser General Public License, Version 2. You
 * can find a copy of the license at:
 * 
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */
package com.sinai.mshab.client.ui.filter;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.sinai.mshab.client.ui.Key;
import com.sinai.mshab.client.ui.aggregate.FormData;
import com.sinai.mshab.client.ui.aggregate.HorizontalComponentList;
import com.sinai.mshab.client.ui.aggregate.TableComponent;

/**
 * This is a filtered table which does not have extra functionality like 'add
 * category', 'sort by', 'show records per page'
 * 
 * In other words this filtered table should be used for predefined report
 * generation where the filters are known, custom and non-volatile.
 * 
 * This table will only show 50 records and has no page navigation.
 * 
 * @author serge
 * 
 */
public class SimpleFilteredTable extends FilteredTable {

	public SimpleFilteredTable() {
		table = new TableComponent(true, historyChangePrefix);
		table.setStyleName("sortableTable");

		// go through the keys and add columns.
		Key key = FormData.getKey();
		String table_name = key.getTableName();
		Iterator it = key.getKeys().keySet().iterator();

		// walking through the cols of the key and adding them as cols to the
		// table.
		while (it.hasNext()) {
			String col_name = (String) it.next();
			column_names.add(table_name + "." + col_name);
		}

		// populate button
		Button populate_button = new Button("Search");
		populate_button.setStyleName("search_button");
		populate_button.addClickListener(new UpdateListener());

		// the hpanel for buttons.
		HorizontalComponentList button_panel = null;
		button_panel = new HorizontalComponentList();
		button_panel.add(populate_button);

		// creating the sort by field.
		Label sortBylabel = new Label("Sort By:");
		sortBylabel.setStyleName("sub_description_label");
		sort_by = new ListBox();
		sort_by.addFocusListener(this);

		// the showing records label, dont need it for now
		showing_records = new Label();
		showing_records.setStyleName("important_blue");

		// nav panel for records
		record_navigation = new HorizontalPanel();

		// adding it all.

		// add(sortby_panel);
		// add(showing_records);
		add(table);
		add(button_panel);
		// add(record_navigation);
	}

	/**
	 * This will construct the sql based on the column names and the
	 * FilterAggregates available.
	 * 
	 * @param the
	 *            sql that will retreive the appropriate data for this table
	 */
	public String constructSQL() {

		String key_table_name = FormData.getKey().getTableName();

		String sql = "SELECT ";

		// we want to remember the columns we are getting back
		// from the server to make sure we dont ask for duplicates
		columns_seen_sofar = new ArrayList();

		// appending prepared columns
		for (int i = 0; i < column_names.size(); i++) {
			String column = (String) column_names.get(i);
			String show = column.replace('.', '_');

			// dont need a comma for the first value.
			if (i == 0) {
				sql += " " + column + " " + show + " ";
				columns_seen_sofar.add(column + " " + show);
			}
			// need commas between column names for all other values.
			else if (!columns_seen_sofar.contains(column + " " + show)) {
				sql += " ," + column + " " + show + " ";
				columns_seen_sofar.add(column + " " + show);
			}
		}

		// appending FilterAggregate columns
		for (int i = 0; i < filterAggregates.size(); i++) {
			FilterAggregate filterAgg = (FilterAggregate) filterAggregates
					.get(i);
			String column = filterAgg.getColumns();

			// append the column to the sql clause
			if (column.trim().length() > 0) {

				// the column comes with a ',' infront if we had no predefined
				// columns this might cause an sql syntax problem.
				if (sql.trim().equals("SELECT")) {
					sql += column.substring(column.indexOf(',') + 1) + " ";
				} else {
					sql += column + " ";
				}
			}
		}

		sql += "FROM ";
		boolean first_table_present = false;
		if (key_table_name != null && key_table_name.trim().length() > 0) {
			sql += key_table_name + " ";
			first_table_present = true;
		}

		// appending FilterAggregate columns
		for (int i = 0; i < filterAggregates.size(); i++) {
			FilterAggregate FilterAggregate = (FilterAggregate) filterAggregates
					.get(i);
			String join = FilterAggregate.getJoin();

			// if the default table was provided, do an inner join
			if (first_table_present
					&& !FilterAggregate.getTableName().equals(key_table_name)) {
				sql += " INNER JOIN " + join + " ";
			}
			// if default table not provided, append the join whatever it
			// happens to be
			// this only needs to be done once.
			else if (!FilterAggregate.getTableName().equals(key_table_name)) {
				sql += " " + join + " ";
				first_table_present = true;
			}
		}

		// adding the WHERE clauses if applicable.
		int number_of_FilterAggregates = filterAggregates.size();
		if (number_of_FilterAggregates != 0) {
			sql += "WHERE ";

			// walking throuhg the FilterAggregates.
			for (int i = 0; i < number_of_FilterAggregates; i++) {
				String agg_wheres = ((FilterAggregate) filterAggregates.get(i))
						.getWheres();

				// dont need and AND for the first clause
				if (i == 0) {
					sql += " " + agg_wheres;
				}
				// need an AND infront for all additional clauses.
				else {
					sql += " AND " + agg_wheres;
				}
			}
		}
		return sql;
	}
}
